using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Memory;
using Senparc.CO2NET;
using Senparc.CO2NET.RegisterServices;
using Senparc.Weixin;
using Senparc.Weixin.RegisterServices;
using Senparc.Weixin.Work;
using Senparc.Weixin.Work.Containers;
using Lzfy_His_Service.Services;
using Lzfy_His_Service.Models.Configuration;
using Lzfy_His_Service.Logging;

namespace Lzfy_His_Service.Configuration
{
    /// <summary>
    /// Senparc企业微信服务配置
    /// </summary>
    public static class SenparcServiceConfiguration
    {
        /// <summary>
        /// 添加Senparc企业微信服务
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="configuration">配置</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection AddSenparcWeChatServices(this IServiceCollection services, IConfiguration configuration)
        {
            // 1. 配置绑定
            services.Configure<SenparcWeChatConfiguration>(configuration.GetSection("SenparcWeChatConfiguration"));
            
            // 2. 验证配置
            var wechatConfig = configuration.GetSection("SenparcWeChatConfiguration").Get<SenparcWeChatConfiguration>();
            if (wechatConfig?.Enabled == true)
            {
                ValidateConfiguration(wechatConfig);
            }

            // 3. 注册Senparc.CO2NET全局服务
            services.AddSenparcGlobalServices(configuration)
                    .AddSenparcWeixinServices(configuration);

            // 4. 注册自定义服务
            services.AddScoped<ISenparcWeChatService, SenparcWeChatService>();
            services.AddScoped<ISenparcCacheService, SenparcCacheService>();
            
            // 5. 注册HTTP客户端
            services.AddHttpClient<ISenparcWeChatService, SenparcWeChatService>(client =>
            {
                client.Timeout = TimeSpan.FromMilliseconds(wechatConfig?.ApiTimeoutMs ?? 30000);
                client.DefaultRequestHeaders.Add("User-Agent", "Lzfy_His_Service/1.0");
            });

            // 6. 配置缓存服务
            ConfigureCacheServices(services, configuration, wechatConfig);

            // 7. 配置日志服务
            ConfigureLoggingServices(services);

            return services;
        }

        /// <summary>
        /// 配置Senparc微信服务
        /// </summary>
        /// <param name="app">应用程序构建器</param>
        /// <param name="env">环境</param>
        /// <param name="configuration">配置</param>
        /// <returns>应用程序构建器</returns>
        public static IApplicationBuilder UseSenparcWeixin(this IApplicationBuilder app, IWebHostEnvironment env, IConfiguration configuration)
        {
            var wechatConfig = configuration.GetSection("SenparcWeChatConfiguration").Get<SenparcWeChatConfiguration>();
            
            if (wechatConfig?.Enabled != true)
            {
                return app;
            }

            // 1. 启用Senparc.CO2NET
            var isProduction = env.IsProduction();
            var senparcSetting = configuration.GetSenparcSetting(isProduction);
            var senparcWeixinSetting = configuration.GetSenparcWeixinSetting(isProduction);
            
            app.UseSenparcGlobal(env, senparcSetting, globalRegister =>
            {
                // CO2NET全局配置
            }, true)
            .UseSenparcWeixin(senparcWeixinSetting, weixinRegister =>
            {
                // 2. 注册企业微信应用
                weixinRegister.RegisterWorkAccount(senparcWeixinSetting, wechatConfig.CorpId, wechatConfig.CorpSecret, "企业微信集成应用");
                
                // 3. 配置企业微信容器
                AccessTokenContainer.Register(wechatConfig.CorpId, wechatConfig.CorpSecret);
            });

            return app;
        }

        /// <summary>
        /// 验证配置
        /// </summary>
        /// <param name="config">配置</param>
        /// <exception cref="ArgumentException">配置无效时抛出</exception>
        private static void ValidateConfiguration(SenparcWeChatConfiguration config)
        {
            var errors = new List<string>();

            if (string.IsNullOrEmpty(config.CorpId))
                errors.Add("CorpId不能为空");
            
            if (string.IsNullOrEmpty(config.CorpSecret))
                errors.Add("CorpSecret不能为空");
            
            if (string.IsNullOrEmpty(config.AgentId))
                errors.Add("AgentId不能为空");
            
            if (string.IsNullOrEmpty(config.RedirectUri))
                errors.Add("RedirectUri不能为空");
            
            if (!Uri.IsWellFormedUriString(config.RedirectUri, UriKind.Absolute))
                errors.Add("RedirectUri格式不正确");
            
            if (!string.IsNullOrEmpty(config.FrontendSuccessUrl) && !Uri.IsWellFormedUriString(config.FrontendSuccessUrl, UriKind.Absolute))
                errors.Add("FrontendSuccessUrl格式不正确");
            
            if (!string.IsNullOrEmpty(config.FrontendErrorUrl) && !Uri.IsWellFormedUriString(config.FrontendErrorUrl, UriKind.Absolute))
                errors.Add("FrontendErrorUrl格式不正确");

            if (config.ApiTimeoutMs <= 0)
                errors.Add("ApiTimeoutMs必须大于0");
            
            if (config.RetryCount < 0)
                errors.Add("RetryCount不能小于0");

            if (errors.Any())
            {
                throw new ArgumentException($"Senparc企业微信配置无效：{string.Join("; ", errors)}");
            }
        }

        /// <summary>
        /// 配置缓存服务
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="configuration">配置</param>
        /// <param name="wechatConfig">微信配置</param>
        private static void ConfigureCacheServices(IServiceCollection services, IConfiguration configuration, SenparcWeChatConfiguration? wechatConfig)
        {
            if (wechatConfig?.Cache?.EnableDistributedCache == true)
            {
                // 配置Redis分布式缓存
                var redisConnectionString = configuration.GetConnectionString("Redis") ?? configuration.GetValue<string>("Redis:ConnectionString");
                
                if (!string.IsNullOrEmpty(redisConnectionString))
                {
                    services.AddStackExchangeRedisCache(options =>
                    {
                        options.Configuration = redisConnectionString;
                        options.InstanceName = "Lzfy_His_Service";
                    });
                }
                else
                {
                    // 如果没有Redis配置，回退到内存缓存
                    services.AddMemoryCache();
                }
            }
            else
            {
                // 使用内存缓存
                services.AddMemoryCache();
            }
        }

        /// <summary>
        /// 配置日志服务
        /// </summary>
        /// <param name="services">服务集合</param>
        private static void ConfigureLoggingServices(IServiceCollection services)
        {
            // 注册自定义日志扩展
            services.AddSingleton<ILoggerProvider, WeChatLoggerProvider>();
        }

        /// <summary>
        /// 添加健康检查
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="configuration">配置</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection AddSenparcHealthChecks(this IServiceCollection services, IConfiguration configuration)
        {
            var wechatConfig = configuration.GetSection("SenparcWeChatConfiguration").Get<SenparcWeChatConfiguration>();
            
            if (wechatConfig?.Enabled == true)
            {
                services.AddHealthChecks()
                    .AddCheck<WeChatHealthCheck>("wechat", tags: new[] { "wechat", "external" });
            }

            return services;
        }
    }

    /// <summary>
    /// 企业微信健康检查
    /// </summary>
    public class WeChatHealthCheck : IHealthCheck
    {
        private readonly ISenparcWeChatService _wechatService;
        private readonly ILogger<WeChatHealthCheck> _logger;

        public WeChatHealthCheck(ISenparcWeChatService wechatService, ILogger<WeChatHealthCheck> logger)
        {
            _wechatService = wechatService;
            _logger = logger;
        }

        public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
        {
            try
            {
                // 验证配置和获取AccessToken
                var isValid = await _wechatService.ValidateConfigurationAsync();
                
                if (isValid)
                {
                    var accessToken = await _wechatService.GetAccessTokenAsync();
                    
                    if (!string.IsNullOrEmpty(accessToken))
                    {
                        return HealthCheckResult.Healthy("企业微信服务正常");
                    }
                    else
                    {
                        return HealthCheckResult.Degraded("无法获取AccessToken");
                    }
                }
                else
                {
                    return HealthCheckResult.Unhealthy("企业微信配置无效");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "企业微信健康检查失败");
                return HealthCheckResult.Unhealthy("企业微信服务异常", ex);
            }
        }
    }

    /// <summary>
    /// Program.cs配置示例
    /// </summary>
    public static class ProgramConfigurationExample
    {
        /// <summary>
        /// 配置服务示例
        /// </summary>
        /// <param name="builder">Web应用程序构建器</param>
        public static void ConfigureServices(WebApplicationBuilder builder)
        {
            var services = builder.Services;
            var configuration = builder.Configuration;

            // 1. 基础服务
            services.AddControllers();
            services.AddEndpointsApiExplorer();
            services.AddSwaggerGen();

            // 2. 认证和授权
            services.AddAuthentication("Bearer")
                .AddJwtBearer("Bearer", options =>
                {
                    // JWT配置
                });
            services.AddAuthorization();

            // 3. 数据库服务
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(configuration.GetConnectionString("DefaultConnection")));

            // 4. Senparc企业微信服务
            services.AddSenparcWeChatServices(configuration);

            // 5. 健康检查
            services.AddSenparcHealthChecks(configuration);

            // 6. 其他服务
            services.AddScoped<IAuthService, AuthService>();
            services.AddScoped<ICaptchaService, CaptchaService>();
        }

        /// <summary>
        /// 配置中间件示例
        /// </summary>
        /// <param name="app">Web应用程序</param>
        /// <param name="env">环境</param>
        public static void ConfigureMiddleware(WebApplication app, IWebHostEnvironment env)
        {
            // 1. 开发环境配置
            if (env.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI();
            }

            // 2. 基础中间件
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseRouting();

            // 3. 认证和授权
            app.UseAuthentication();
            app.UseAuthorization();

            // 4. Senparc微信服务
            app.UseSenparcWeixin(env, app.Configuration);

            // 5. 控制器映射
            app.MapControllers();

            // 6. 健康检查
            app.MapHealthChecks("/health");
            app.MapHealthChecks("/health/wechat", new HealthCheckOptions
            {
                Predicate = check => check.Tags.Contains("wechat")
            });
        }
    }
}